package l2hc.gameserver.model.instances;

import java.util.Collection;
import java.util.StringTokenizer;

import l2hc.gameserver.Config;
import l2hc.gameserver.cache.Msg;
import l2hc.gameserver.data.xml.holder.ItemHolder;
import l2hc.gameserver.data.xml.holder.SkillAcquireHolder;
import l2hc.gameserver.model.Player;
import l2hc.gameserver.model.Skill;
import l2hc.gameserver.model.SkillLearn;
import l2hc.gameserver.model.base.AcquireType;
import l2hc.gameserver.model.base.ClassId;
import l2hc.gameserver.model.entity.olympiad.Olympiad;
import l2hc.gameserver.network.serverpackets.NpcHtmlMessage;
import l2hc.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import l2hc.gameserver.network.serverpackets.PledgeStatusChanged;
import l2hc.gameserver.network.serverpackets.SkillList;
import l2hc.gameserver.network.serverpackets.components.SystemMsg;
import l2hc.gameserver.tables.SkillTable;
import l2hc.gameserver.templates.item.ItemTemplate;
import l2hc.gameserver.templates.npc.NpcTemplate;
import l2hc.gameserver.utils.HtmlUtils;
import l2hc.gameserver.utils.Util;

/**
 * @author KilRoy
 * Class Master (Test Server Helper) off version
 * Change Class: Change available base class
 * Become Noble: Adding noble status for player
 * Learn Skill: Learn all available skill for this base class
 * Increase Clan level: Change clan level
 * Item Sale: Sale all items available in High Five (quest, recipes, consumable, etc...)
 */
public final class ClassChangerInstance extends MerchantInstance
{
	
	private static final long serialVersionUID = -8591288735085168566L;

	public ClassChangerInstance(int objectId, NpcTemplate template)
	{
		super(objectId, template);
	}

	private String makeMessage(Player player)
	{
		ClassId classId = player.getClassId();

		int jobLevel = classId.getLevel();
		int level = player.getLevel();

		StringBuilder html = new StringBuilder();
		if(Config.ALLOW_CLASS_MASTERS_LIST.isEmpty() || !Config.ALLOW_CLASS_MASTERS_LIST.contains(jobLevel))
			jobLevel = 4;
		if((level >= 20 && jobLevel == 1 || level >= 40 && jobLevel == 2 || level >= 76 && jobLevel == 3) && Config.ALLOW_CLASS_MASTERS_LIST.contains(jobLevel))
		{
			ItemTemplate item = ItemHolder.getInstance().getTemplate(Config.CLASS_MASTERS_PRICE_ITEM);
			if(Config.CLASS_MASTERS_PRICE_LIST[jobLevel] > 0)
				html.append("Price: ").append(Util.formatAdena(Config.CLASS_MASTERS_PRICE_LIST[jobLevel])).append(" ").append(item.getName()).append("<br1>");
			for(ClassId cid : ClassId.VALUES)
			{
				if(cid == ClassId.inspector)
					continue;
				if(cid.childOf(classId) && cid.getLevel() == classId.getLevel() + 1)
					html.append("<a action=\"bypass -h npc_").append(getObjectId()).append("_change_class ").append(cid.getId()).append(" ").append(Config.CLASS_MASTERS_PRICE_LIST[jobLevel]).append("\">").append(HtmlUtils.htmlClassName(cid.getId())).append("</a><br>");
			}
			player.sendPacket(new NpcHtmlMessage(player, this).setHtml(html.toString()));
		}
		else
			switch(jobLevel)
			{
				case 1:
					html.append("Come back here when you reached level 20 to change your class.");
					break;
				case 2:
					html.append("Come back here when you reached level 40 to change your class.");
					break;
				case 3:
					html.append("Come back here when you reached level 76 to change your class.");
					break;
				case 4:
					html.append("There is no class changes for you any more.");
					break;
			}
		return html.toString();
	}

	@Override
	public String getHtmlPath(int npcId, int val, Player player)
	{
		String pom = "";
		if(val == 0)
			pom = "" + npcId;
		else
			pom = npcId + "-" + val;

		return "classmaster/" + pom + ".htm";
	}

	@Override
	public void onBypassFeedback(Player player, String command)
	{
		if(!canBypassCheck(player, this))
			return;

		NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
		
		StringTokenizer st = new StringTokenizer(command);
		if(command.startsWith("change_class_now"))
		{
			html.setFile("classmaster/class-change.htm");
			html.replace("%classmaster%", makeMessage(player));
			player.sendPacket(html);
		}
		if(st.nextToken().equals("change_class"))
		{
			int val = Integer.parseInt(st.nextToken());
			long price = Long.parseLong(st.nextToken());
			if(player.getInventory().destroyItemByItemId(Config.CLASS_MASTERS_PRICE_ITEM, price))
				changeClass(player, val);
			else if(Config.CLASS_MASTERS_PRICE_ITEM == 57)
				player.sendPacket(Msg.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
			else
				player.sendPacket(SystemMsg.INCORRECT_ITEM_COUNT);
		}
		else if(command.startsWith("become_noble"))
		{
			if (!player.isNoble())
			{
				Olympiad.addNoble(player);
				player.setNoble(true);
				player.updatePledgeClass();
				player.updateNobleSkills();
				player.sendPacket(new SkillList(player));
				player.broadcastUserInfo(true);
				
				html.setFile("classmaster/noble-ok.htm");
				player.sendPacket(html);
			}
			else
			{
				html.setFile("classmaster/you-noble.htm");
				player.sendPacket(html);
			}
		}
		else if(command.startsWith("learn_skills"))
		{
			if(player.getVar("TSHGAS") == null)
			{
				GiveAllSkills(player);
				player.setVar("TSHGAS", "all", -1);
				html.setFile("classmaster/skill-learn.htm");
				player.sendPacket(html);
			}
			else
			{
				html.setFile("classmaster/no-skill-learn.htm");
				player.sendPacket(html);
			}
		}
		else if(command.startsWith("increase_clan_level"))
		{
			if (!player.isClanLeader())
			{
				html.setFile("classmaster/no-clan-leader.htm");
				player.sendPacket(html);
			}
			else if (player.getClan().getLevel() >= 5)
			{
				html.setFile("classmaster/no-clan-level.htm");
				player.sendPacket(html);
			}
			else
			{
				player.getClan().setLevel(5);
				player.getClan().updateClanInDB();
				
				PledgeShowInfoUpdate pu = new PledgeShowInfoUpdate(player.getClan());
				PledgeStatusChanged ps = new PledgeStatusChanged(player.getClan());
				
				for(Player member : player.getClan().getOnlineMembers(0))
				{
					member.updatePledgeClass();
					member.sendPacket(Msg.CLANS_SKILL_LEVEL_HAS_INCREASED, pu, ps);
					member.broadcastUserInfo(true);
				}
				
				html.setFile("classmaster/clan-level-set.htm");
				player.sendPacket(html);
			}
		}
		else
			super.onBypassFeedback(player, command);
	}
	
	private void GiveAllSkills(Player player)
	{
		int unLearnable = 0;
		int skillCounter = 0;
		Collection<SkillLearn> skills = SkillAcquireHolder.getInstance().getAvailableSkills(player, AcquireType.NORMAL);
		while(skills.size() > unLearnable)
		{
			unLearnable = 0;
			for(SkillLearn s : skills)
			{
				Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
				if(sk == null || !sk.getCanLearn(player.getClassId()))
				{
					unLearnable++;
					continue;
				}
				if(player.getSkillLevel(sk.getId()) == -1)
					skillCounter++;
				player.addSkill(sk, true);
			}
			skills = SkillAcquireHolder.getInstance().getAvailableSkills(player, AcquireType.NORMAL);
		}

		player.sendMessage("You learn all " + skillCounter + " skills.");
		player.sendPacket(new SkillList(player));
	}

	private void changeClass(Player player, int val)
	{
		if(player.getClassId().getLevel() == 3)
			player.sendPacket(Msg.YOU_HAVE_COMPLETED_THE_QUEST_FOR_3RD_OCCUPATION_CHANGE_AND_MOVED_TO_ANOTHER_CLASS_CONGRATULATIONS);
		else
			player.sendPacket(Msg.CONGRATULATIONS_YOU_HAVE_TRANSFERRED_TO_A_NEW_CLASS);

		player.setClassId(val, false, false);
		player.broadcastCharInfo();
	}
}